import re

from django.conf import settings
from django.contrib.auth.backends import ModelBackend

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadData

from users import constants
from .models import User
# 属于当前子应用的公共函数或类库方法
def jwt_response_payload_handler(token, user=None, request=None):
    """
    自定义jwt认证成功返回数据
    :param token: 生成token的对象
    :param user: 当前已经登陆的用户[ 在登陆视图/注册视图中传递进来的 ]
    :param request: 本次的请求对象
    :return:
    """
    return {
        'token': token,
        'user_id': user.id,
        'username': user.username
    }


def get_user_by_account(account):
    """根据账号信息获取用户"""
    try:
        if re.match('^1[3-9]\d{9}$', account):
            # 用户提交的是手机号
            user = User.objects.filter(mobile=account).first()
        else:
            user = User.objects.filter(username=account).first()

    except User.DoesNotExist:
        # 找不到对应的用户
        return None

    else:
        return user

class UsernameMobileAuthBackend(ModelBackend):
    """
    JWT扩展的登录视图，在收到用户名与密码时，也是调用Django的认证系统中提供的authenticate()来检查用户名与密码是否正确。

我们可以通过修改Django认证系统的认证后端（主要是authenticate方法）来支持登录账号既可以是用户名也可以是手机号。
    """
    def authenticate(self, request, username=None, password=None, **kwargs):
        """
        根据用户提供的信息，返回登陆用户，自定义用户认证
        :param request: 本次请求对象
        :param username: 用户名或者手机号[并不一定是用户名!!!]
        :param password: 登陆密码
        :return:
        """
        user = get_user_by_account(username)
        if user is not None and user.check_password(password):
            return user


def generate_verify_email_url(self):
    """
    生成验证邮箱的url
    """
    serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
    data = {'user_id': self.id, 'email': self.email}
    token = serializer.dumps(data).decode()
    verify_url = 'http://www.meiduo.site:8080/success_verify_email.html?token=' + token
    return verify_url


def check_verify_email_token(token):
    serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
    try:

        token = serializer.loads(token)
        user_id = token["user_id"]
    except BadData:
        user_id = None
    return user_id

